import { useBoolean } from 'ahooks';
import { App } from 'antd';
import React, { useCallback, useMemo, useState } from 'react';

import { SvgIcon } from '@/components/icon';
import FormLabel from '@/components/MyBox/FormLabel';
import MyModal from '@/components/MyModal';
import QuestionTip from '@/components/tooltip/QuestionTip';
import { t } from '@/locales/i18n';
import { VariableItemType } from '@/types/app/type';
import { FlowNodeInputTypeEnum, WorkflowIOValueTypeEnum } from '@/types/workflow/constant';
import { FlowNodeInputItemType } from '@/types/workflow/io';

import InputTypeConfig from './InputTypeConfig';

// 类型适配器：将 FlowNodeInputItemType 转换为 InputTypeConfig 期望的类型
type InputTypeConfigData = VariableItemType & {
  list?: { id: string; value: string; label: string }[];
  customInputConfig?: {
    selectValueTypeList?: WorkflowIOValueTypeEnum[];
  };
  renderTypeList?: FlowNodeInputTypeEnum[];
  pattern?: string;
  isArray?: boolean;
  valueType?: WorkflowIOValueTypeEnum;
  [key: string]: any; // 允许其他属性
};

export const defaultInput: FlowNodeInputItemType = {
  renderTypeList: [FlowNodeInputTypeEnum.reference], // Can only choose one here
  selectedTypeIndex: 0,
  valueType: WorkflowIOValueTypeEnum.string,
  canEdit: true,
  key: '',
  label: '',
  description: '',
  defaultValue: '',
  list: [{ label: '', value: '' }],
};

const FieldEditModal = ({
  defaultValue,
  keys = [],
  hasDynamicInput,
  onClose,
  onSubmit,
}: {
  defaultValue: FlowNodeInputItemType;
  keys: string[];
  hasDynamicInput: boolean;
  onClose: () => void;
  onSubmit: (data: FlowNodeInputItemType) => void;
}) => {
  const { message } = App.useApp();
  const inputTypeList = useMemo(
    () =>
      [
        [
          {
            icon: 'core/workflow/inputType/reference',
            label: t('core.workflow.inputType.Reference'),
            value: [FlowNodeInputTypeEnum.reference],
            defaultValueType: WorkflowIOValueTypeEnum.string,
          },
          {
            icon: 'core/workflow/inputType/input',
            label: t('core.workflow.inputType.textInput'),
            value: [FlowNodeInputTypeEnum.input, FlowNodeInputTypeEnum.reference],
            defaultValueType: WorkflowIOValueTypeEnum.string,
          },
          {
            icon: 'core/workflow/inputType/jsonEditor',
            label: t('core.workflow.inputType.JSON Editor'),
            value: [FlowNodeInputTypeEnum.JSONEditor, FlowNodeInputTypeEnum.reference],
            defaultValueType: WorkflowIOValueTypeEnum.string,
          },
          {
            icon: 'core/workflow/inputType/numberInput',
            label: t('core.workflow.inputType.number input'),
            value: [FlowNodeInputTypeEnum.numberInput, FlowNodeInputTypeEnum.reference],
            defaultValueType: WorkflowIOValueTypeEnum.number,
          },
          {
            icon: 'core/workflow/inputType/option',
            label: t('core.workflow.inputType.select'),
            value: [FlowNodeInputTypeEnum.select, FlowNodeInputTypeEnum.reference],
            defaultValueType: WorkflowIOValueTypeEnum.string,
          },
          {
            icon: 'core/workflow/inputType/switch',
            label: t('core.workflow.inputType.switch'),
            value: [FlowNodeInputTypeEnum.switch, FlowNodeInputTypeEnum.reference],
            defaultValueType: WorkflowIOValueTypeEnum.boolean,
          },
        ],
        [
          {
            icon: 'core/workflow/inputType/selectLLM',
            label: t('core.workflow.inputType.selectLLMModel'),
            value: [FlowNodeInputTypeEnum.selectLLMModel],
            defaultValueType: WorkflowIOValueTypeEnum.string,
          },
          {
            icon: 'core/workflow/inputType/selectDataset',
            label: t('core.workflow.inputType.selectDataset'),
            value: [FlowNodeInputTypeEnum.selectDataset],
            defaultValueType: WorkflowIOValueTypeEnum.selectDataset,
          },
          ...(hasDynamicInput
            ? []
            : [
                {
                  icon: 'core/workflow/inputType/dynamic',
                  label: t('core.workflow.inputType.dynamicTargetInput'),
                  value: [FlowNodeInputTypeEnum.addInputParam],
                  defaultValueType: WorkflowIOValueTypeEnum.dynamic,
                },
              ]),
        ],
        [
          {
            icon: 'core/workflow/inputType/customVariable',
            label: t('core.workflow.inputType.custom'),
            value: [FlowNodeInputTypeEnum.customVariable],
            defaultValueType: WorkflowIOValueTypeEnum.string,
            description: t('variable.select type_desc'),
          },
        ],
      ] as {
        icon: string;
        label: string;
        value: FlowNodeInputTypeEnum[];
        defaultValueType: WorkflowIOValueTypeEnum;
        description?: string;
      }[][],
    [hasDynamicInput],
  );

  const isEdit = !!defaultValue.key;

  const [data, setData] = useState<FlowNodeInputItemType>(defaultValue);

  const renderTypeList = useMemo(() => data.renderTypeList, [data]);
  const inputType = renderTypeList[0] || FlowNodeInputTypeEnum.reference;
  const valueType = useMemo(() => data.valueType, [data]);

  const [isToolInput, { toggle: setIsToolInput }] = useBoolean(!!data.toolDescription);

  const maxLength = useMemo(() => data.maxLength, [data]);
  const max = useMemo(() => data.max, [data]);
  const min = useMemo(() => data.maxLength, [data]);
  const selectValueTypeList = useMemo(() => data?.customInputConfig?.selectValueTypeList, [data]);
  const defaultInputValue = useMemo(() => data.defaultValue, [data]);

  const defaultValueType = useMemo(
    () =>
      inputTypeList.flat().find((item) => item.value[0] === inputType)?.defaultValueType ||
      WorkflowIOValueTypeEnum.string,
    [inputType, inputTypeList],
  );

  const onSubmitSuccess = useCallback(
    (data: FlowNodeInputItemType, action: 'confirm' | 'continue') => {
      data.label = data?.label?.trim();
      data.key = data?.key?.trim();

      if (!data.label) {
        return message.warning(t('core.module.edit.Field Name Cannot Be Empty'));
      }

      if (!data.key) {
        return message.warning(t('field_key_cannot_be_empty'));
      }

      // Auto set valueType
      if (
        data.renderTypeList[0] !== FlowNodeInputTypeEnum.reference &&
        data.renderTypeList[0] !== FlowNodeInputTypeEnum.customVariable
      ) {
        data.valueType = defaultValueType;
      }

      // Remove required
      if (
        data.renderTypeList[0] === FlowNodeInputTypeEnum.addInputParam ||
        data.renderTypeList[0] === FlowNodeInputTypeEnum.customVariable
      ) {
        data.required = false;
      }

      const isChangeKey = defaultValue.key !== data.key;
      // create check key
      if (keys.includes(data.key)) {
        if (!isEdit || isChangeKey) {
          return message.warning(t('field_name_already_exists'));
        }
      }

      // Focus remove toolDescription
      if (isToolInput && data.renderTypeList.includes(FlowNodeInputTypeEnum.reference)) {
        data.toolDescription = data.description;
      } else {
        data.toolDescription = undefined;
      }

      data.key = data.label;

      if (action === 'confirm') {
        onSubmit(data);
        onClose();
      } else if (action === 'continue') {
        onSubmit(data);
        message.success(t('common.Add Success'));
        // reset(defaultInput);
        setData(defaultInput);
      }

      return undefined;
    },
    [
      defaultValue.key,
      defaultValueType,
      isEdit,
      isToolInput,
      keys,
      onSubmit,
      message,
      onClose,
      setData,
    ],
  );
  const onSubmitError = useCallback(
    (e: Record<string, any>) => {
      const errorItem = Object.values(e).find((item: any) => item?.message);
      if (errorItem?.message) {
        message.warning(errorItem.message);
      }
    },
    [message],
  );

  return (
    <MyModal
      isOpen
      onClose={onClose}
      iconSrc="/imgs/workflow/extract.png"
      title={isEdit ? t('edit_input') : t('add_new_input')}
      maxW={['90vw', '1028px']}
      w="100%"
      isCentered
    >
      <div className="flex" style={{ height: '560px' }}>
        <div className="flex gap-4 p-8">
          <div className="flex items-center">
            <FormLabel className="font-medium text-gray-600">
              {t('core.module.Input Type')}
            </FormLabel>
            <div className="flex flex-col gap-4">
              {inputTypeList.map((list, index) => {
                return (
                  <div className="mt-5 grid grid-cols-3 gap-4" key={index}>
                    {list.map((item) => {
                      const isSelected = inputType === item.value[0];
                      return (
                        <div
                          className="flex cursor-pointer items-center rounded-md p-3 text-sm font-medium"
                          key={item.label}
                          style={{
                            border: isSelected ? '1px solid #3370FF' : '1px solid #DFE2EA',
                            boxShadow: isSelected
                              ? '0px 0px 0px 2.4px rgba(51, 112, 255, 0.15)'
                              : 'none',
                          }}
                          onClick={() => {
                            setData((prev) => {
                              return {
                                ...prev,
                                renderTypeList: item.value,
                              };
                            });
                          }}
                        >
                          <SvgIcon
                            className="mr-2"
                            icon={item.icon as any}
                            size={20}
                            color={isSelected ? 'text-primary-600' : 'text-gray-600'}
                          />

                          <span className={`${isSelected ? 'text-gray-900' : 'text-gray-600'}`}>
                            {item.label}
                          </span>
                          {item.description && <QuestionTip title={item.description} />}
                        </div>
                      );
                    })}
                  </div>
                );
              })}
            </div>
          </div>
        </div>
        {/* input type config */}
        <InputTypeConfig
          data={data as InputTypeConfigData}
          setData={(newData) => {
            if (typeof newData === 'function') {
              setData((prev) => newData(prev as InputTypeConfigData) as FlowNodeInputItemType);
            } else {
              setData(newData as FlowNodeInputItemType);
            }
          }}
          type="plugin"
          isEdit={isEdit}
          inputType={inputType}
          defaultValueType={defaultValueType}
          selectValueTypeList={selectValueTypeList}
          isToolInput={isToolInput}
          setIsToolInput={setIsToolInput}
          onClose={onClose}
          onSubmitSuccess={(data, action) =>
            onSubmitSuccess(data as unknown as FlowNodeInputItemType, action)
          }
          onSubmitError={onSubmitError}
        />
      </div>
    </MyModal>
  );
};

export default React.memo(FieldEditModal);
